//==============================================================================
#include "CFont.h"

//==============================================================================
CFont::CFont() {
    OldString[0] = '\0';

    DisplayList_Font = 0;
};

//==============================================================================
bool CFont::OnLoad(char* File) {
    for(int i = 0;i <= 255;i++) {
        CTexture tempTexture;

        char Buffer[255];
        sprintf(Buffer, "./font/%d.png", i);

        FILE* FileHandle = fopen(Buffer, "r");

        if(FileHandle == NULL) {
            tempTexture.OnLoad("./font/blank.png");
        }else{
            fclose(FileHandle);
            tempTexture.OnLoad(Buffer);
        }

        Tex_FontList.push_back(tempTexture);
    }

    return true;
};

//------------------------------------------------------------------------------
void CFont::OnRender(char* String, int OffsetX, int OffsetY) {
    glAlphaFunc(GL_GREATER,0.1);
    glEnable(GL_ALPHA_TEST);

    int X = 0;
    int Y = 0;

    int LineLength = 0;

    for(int i = 0;i < strlen(String);i++) {
        int Character = (int)String[i];

        if(LineLength > 760) break;

        if(String[i]== '\n') {
            continue;
        }

        if(String[i] == ' ') {
            LineLength += 28 / 4;
            X += 28 / 4;
            continue;
        }

        Tex_FontList[Character].RenderQuad(OffsetX + X, OffsetY + Y, 16, 16);

        X += (GetCharWidth(String[i]) / 4);

        LineLength += (GetCharWidth(String[i]) / 4);
    }

    glDisable(GL_ALPHA_TEST);
}

//------------------------------------------------------------------------------
void CFont::OnRender_Center(char* String) {
    if(!strcmp(OldString, String)) {
        glCallList(DisplayList_Font);
    }else{
        glDeleteLists(DisplayList_Font, 1);

        strcpy(OldString, String);

        LineList.clear();

        int MaxLength = 750;
        int CurrentLength = 0;

        int Start   = 0;
        int End     = 0;

        int X = 0;
        int Y = 64;
        for(int i = 0;i < strlen(String);i++) {
            int CharWidth = GetCharWidth(String[i]);

            CurrentLength += CharWidth;

            if(CurrentLength > MaxLength || String[i] == '\n') {
                End = i;

                if(String[i] != '\n') {
                    for(int j = End;j >= 0;j--) {
                        if(String[j] == '\n') {
                            continue;
                        }

                        if(String[j] == ' ') {
                            End = j;
                            break;
                        }
                    }
                }

                int LineLength = 0;

                for(int j = Start;j < End;j++) {
                    if(j >= strlen(String)) break;

                    if(String[j] == '\n') {
                        continue;
                    }

                    LineLength += GetCharWidth(String[j]);
                }

                int OffsetX = 400 - (LineLength / 2);

                CFontLine FontLine;
                FontLine.OffsetX = OffsetX;

                int k = 0;
                for(int j = Start;j < End;j++) {
                    if(j >= strlen(String)) break;

                    FontLine.Text[k] = String[j];

                    k++;
                }

                FontLine.Text[k] = '\0';

                LineList.push_back(FontLine);

                i = End;

                Start   = End;
                End     = Start;

                X = 0;
                Y += 64;

                CurrentLength = 0;
            }else{
                End++;
            }
        }

        End++;

        X = 0;

        int LineLength = 0;

        for(int j = Start;j < End;j++) {
            if(j >= strlen(String)) break;

            if(String[j] == '\n') {
                continue;
            }

            LineLength += 32;
        }

        int OffsetX = 400 - (LineLength / 2);

        CFontLine FontLine;
        FontLine.OffsetX = OffsetX;

        int k = 0;
        for(int j = Start;j < End;j++) {
            if(j >= strlen(String)) break;

            FontLine.Text[k] = String[j];

            k++;
        }

        FontLine.Text[k] = '\0';

        LineList.push_back(FontLine);

        DisplayList_Font = glGenLists(1);

        glNewList(DisplayList_Font, GL_COMPILE);

            glEnable(GL_BLEND);

            glAlphaFunc(GL_GREATER, 0.5);
            glEnable(GL_ALPHA_TEST);

            X = 0;
            Y = 320 - ((LineList.size() * 58) / 2);

            for(int i = 0;i < LineList.size();i++) {
                for(int j = 0;j < strlen(LineList[i].Text);j++) {
                    int Character = (int)LineList[i].Text[j];
                    int CharWidth = GetCharWidth(LineList[i].Text[j]);

                    if(LineList[i].Text[j] == '\n') {
                        continue;
                    }

                    if(LineList[i].Text[j] == ' ') {
                        X += CharWidth;
                        continue;
                    }

                    Tex_FontList[Character].RenderQuad(LineList[i].OffsetX + X, Y, 64, 64);

                    X += CharWidth;
                }
                X = 0;
                Y += 58;
            }

            glDisable(GL_ALPHA_TEST);

            glDisable(GL_BLEND);

        glEndList();
    }
};

//==============================================================================
int CFont::GetCharWidth(char Character) {
    switch(Character) {
        case ',': return 22;
        case '\'': return 22;
        case ';': return 22;
        case '-': return 24;

        case ' ': return 28;
        case '.': return 24;

        case '0': return 34;
        case '1': return 34;
        case '2': return 34;
        case '3': return 34;
        case '4': return 34;
        case '5': return 34;
        case '6': return 34;
        case '7': return 34;
        case '8': return 34;
        case '9': return 34;

        case ':': return 22;
        case '_': return 28;

        case ')': return 28;
        case '(': return 28;

        case 'a': return 32;
        case 'b': return 34;
        case 'c': return 32;
        case 'd': return 32;
        case 'e': return 32;
        case 'f': return 26;
        case 'g': return 32;
        case 'h': return 32;
        case 'i': return 18;
        case 'j': return 28;
        case 'k': return 32;
        case 'l': return 18;
        case 'm': return 48;
        case 'n': return 32;
        case 'o': return 32;
        case 'p': return 34;
        case 'q': return 32;
        case 'r': return 26;
        case 's': return 28;
        case 't': return 26;
        case 'u': return 32;
        case 'v': return 32;
        case 'w': return 46;
        case 'x': return 32;
        case 'y': return 32;
        case 'z': return 32;

        case 'A': return 32;
        case 'B': return 34;
        case 'C': return 32;
        case 'D': return 34;
        case 'E': return 32;
        case 'F': return 26;
        case 'G': return 38;
        case 'H': return 36;
        case 'I': return 16;
        case 'J': return 28;
        case 'K': return 32;
        case 'L': return 24;
        case 'M': return 46;
        case 'N': return 36;
        case 'O': return 36;
        case 'P': return 34;
        case 'Q': return 36;
        case 'R': return 34;
        case 'S': return 28;
        case 'T': return 30;
        case 'U': return 36;
        case 'V': return 36;
        case 'W': return 50;
        case 'X': return 34;
        case 'Y': return 34;
        case 'Z': return 34;
    }

    return 0;
}

//==============================================================================
